package trading.bo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import trading.dataentry.MonitoredStocks;
import trading.dataentry.OptionPositionOrOrder;
import trading.dataentry.StockPositionOrOrder;
import trading.util.Constants;
import trading.util.IBMsgIDGen;

import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.AmazonSimpleDBClient;
import com.amazonaws.services.simpledb.model.Attribute;
import com.amazonaws.services.simpledb.model.CreateDomainRequest;
import com.amazonaws.services.simpledb.model.DeleteAttributesRequest;
import com.amazonaws.services.simpledb.model.Item;
import com.amazonaws.services.simpledb.model.PutAttributesRequest;
import com.amazonaws.services.simpledb.model.ReplaceableAttribute;
import com.amazonaws.services.simpledb.model.SelectRequest;
import com.ib.client.Contract;

public class DBAccessorBO {

    private AmazonSimpleDB sdb;

    private enum Domain {
        Account_Names, Current_Account_Status, Current_Open_Orders, Monitored_Stock_Tickers, Current_Stock_Positions, Current_Option_Positions, Market_Sentiment, Past_Six_Day_VIX_Spot, Past_Five_Day_VIX_Contango;
    }

    public void setAwsCredentialFileLocation(File awsCredentialFileLocation)
            throws FileNotFoundException, IllegalArgumentException, IOException {
        this.sdb = new AmazonSimpleDBClient(new PropertiesCredentials(
                awsCredentialFileLocation));
        checkDomains();
    }

    private void checkDomains() {
        List<String> domainNames = sdb.listDomains().getDomainNames();
        for (Domain domain : Domain.values()) {
            if (!domainNames.contains(domain.name())) {
                sdb.createDomain(new CreateDomainRequest(domain.name()));
            }
        }
    }

    public void updateMonitoredStockTickersLastPrice(
            IBMsgIDGen.IBMsgBean msgBean, double lastPrice) {
        String ticker = msgBean.getOtherInfo().get(Constants.TICKER);
        if (ticker == null) {
            // Log error message here
            return;
        }
        List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
        replaceableAttributes.add(new ReplaceableAttribute("last_price",
                lastPrice + "", true));
        System.out.println("Updating stk price for : " + ticker + ". It is "
                + lastPrice);
        sdb.putAttributes(new PutAttributesRequest(
                Domain.Monitored_Stock_Tickers.name(), ticker,
                replaceableAttributes));
    }

    public void updateAvailableFunds(String availableFund) {
        List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
        replaceableAttributes.add(new ReplaceableAttribute("available_fund",
                availableFund + "", true));
        System.out.println("Updating available fund, it is " + availableFund);
        sdb.putAttributes(new PutAttributesRequest(
                Domain.Current_Account_Status.name(), Constants.ACCOUNT_ID,
                replaceableAttributes));
    }

    public double getAvailableFund() {
        String selectExpression = "select available_fund from `"
                + Domain.Current_Account_Status.name()
                + "` where itemName() = '" + Constants.ACCOUNT_ID + "'";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        String availableFund = "";
        for (Item item : items) {
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("available_fund")) {
                    availableFund = attribute.getValue();
                }
            }
        }
        return Double.parseDouble(availableFund);
    }

    public double getNetLiquidation() {
        String selectExpression = "select net_liquidation from `"
                + Domain.Current_Account_Status.name()
                + "` where itemName() = '" + Constants.ACCOUNT_ID + "'";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        String netLiquidation = "";
        for (Item item : items) {
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("net_liquidation")) {
                    netLiquidation = attribute.getValue();
                }
            }
        }
        return Double.parseDouble(netLiquidation);
    }

    public void updateNetLiquidation(String netLiquidation) {
        List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
        replaceableAttributes.add(new ReplaceableAttribute("net_liquidation",
                netLiquidation + "", true));
        System.out.println("Updating net liquidation. It is " + netLiquidation);
        sdb.putAttributes(new PutAttributesRequest(
                Domain.Current_Account_Status.name(), Constants.ACCOUNT_ID,
                replaceableAttributes));
    }

    public void updateTotalCashBalance(String totalCashBalance) {
        List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
        replaceableAttributes.add(new ReplaceableAttribute(
                "total_cash_balance", totalCashBalance + "", true));
        System.out.println("Updating total cash balance. It is "
                + totalCashBalance);
        sdb.putAttributes(new PutAttributesRequest(
                Domain.Current_Account_Status.name(), Constants.ACCOUNT_ID,
                replaceableAttributes));
    }

    public void updatePortfolioStockPositions(Contract contract, int position) {
        if (position == 0) {
            this.deletePortfolioStockPosition(contract.m_symbol + "_" + Constants.ACCOUNT_ID);
        } else {
            List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
            replaceableAttributes.add(new ReplaceableAttribute("shares",
                    position + "", true));
            sdb.putAttributes(new PutAttributesRequest(
                    Domain.Current_Stock_Positions.name(), contract.m_symbol + "_" + Constants.ACCOUNT_ID,
                    replaceableAttributes));
        }
    }
    
    public void updateAccountId(String accountNumber) {
        if (Constants.ACCOUNT_ID == null || Constants.ACCOUNT_ID.isEmpty()) {
            String selectExpression = "select * from `"
                    + Domain.Account_Names.name() + "`";
            SelectRequest selectRequest = new SelectRequest(selectExpression);
            List<Item> items = sdb.select(selectRequest).getItems();
            
            for (int i = 0; i < items.size(); i++) {
                Item item = items.get(i);
                if (item.getName().equals(accountNumber)) {
                    for (Attribute attribute : item.getAttributes()) {
                        if (attribute.getName().equals("accountId")) {
                            Constants.ACCOUNT_ID = attribute.getValue();
                            return;
                        }
                    }
                }
            }
            
            List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
            replaceableAttributes.add(new ReplaceableAttribute(
                    "accountId", items.size() + "", true));
            sdb.putAttributes(new PutAttributesRequest(
                    Domain.Account_Names.name(), accountNumber,
                    replaceableAttributes));
            Constants.ACCOUNT_ID = items.size() + "";
        }
    }

    private void deletePortfolioStockPosition(String tickerAndAcctId) {
        sdb.deleteAttributes(new DeleteAttributesRequest(
                Domain.Current_Stock_Positions.name(), tickerAndAcctId));
    }

    public List<StockPositionOrOrder> getPortfolioStockPositions() {
        String selectExpression = "select * from `"
                + Domain.Current_Stock_Positions.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        List<StockPositionOrOrder> stockPositions = new ArrayList<StockPositionOrOrder>();
        for (Item item : items) {
            String itemName = item.getName();
            String[] tmp = itemName.split("_");
            if (!tmp[1].equals(Constants.ACCOUNT_ID)) {
                continue;
            }
            String tiker = tmp[0];
            StockPositionOrOrder position = new StockPositionOrOrder();
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("shares")) {
                    position.setQuantity(attribute.getValue());
                }
            }
            position.setTicker(tiker);
            stockPositions.add(position);
        }
        return stockPositions;
    }

    public void updatePortfolioOptionPositions(Contract contract, int position) {
        String primaryKey = contract.m_symbol + " " + contract.m_expiry + " "
                + contract.m_strike + " " + contract.m_right + " " + Constants.ACCOUNT_ID;
        if (position == 0) {
            this.deletePortfolioOptionPosition(primaryKey);
        } else {
            List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
            replaceableAttributes.add(new ReplaceableAttribute("multiplier",
                    contract.m_multiplier, true));
            replaceableAttributes.add(new ReplaceableAttribute("position",
                    position + "", true));

            sdb.putAttributes(new PutAttributesRequest(
                    Domain.Current_Option_Positions.name(), primaryKey,
                    replaceableAttributes));
        }
    }

    private void deletePortfolioOptionPosition(String itemName) {
        sdb.deleteAttributes(new DeleteAttributesRequest(
                Domain.Current_Option_Positions.name(), itemName));
    }

    public List<OptionPositionOrOrder> getPortfolioOptionPositions() {
        String selectExpression = "select * from `"
                + Domain.Current_Option_Positions.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        List<OptionPositionOrOrder> optionPositions = new ArrayList<OptionPositionOrOrder>();

        for (Item item : items) {
            OptionPositionOrOrder optionPosition = new OptionPositionOrOrder();
            String itemName = item.getName();
            String[] components = itemName.split(" ");
            if (!components[4].equals(Constants.ACCOUNT_ID)) {
                continue;
            }
            optionPosition.setUnderlyingTick(components[0]);
            optionPosition.setExpiration(components[1]);
            optionPosition.setStrikePrice(components[2]);
            optionPosition.setCallOrPut(components[3]);

            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("position")) {
                    optionPosition.setPosition(attribute.getValue());
                } else if (attribute.getName().equals("multiplier")) {
                    optionPosition.setMultiPlier(attribute.getValue());
                }
            }
            optionPositions.add(optionPosition);
        }
        return optionPositions;
    }

    public void updateHistoricalLowPriceAndDate(IBMsgIDGen.IBMsgBean msgBean,
            String lowPrice, String date) {
        String ticker = msgBean.getOtherInfo().get(Constants.TICKER);
        if (ticker == null) {
            return;
        }
        updateHistoricalLowPriceAndDate(ticker, lowPrice, date);
    }

    public void updateHistoricalLowPriceAndDate(String ticker, String lowPrice,
            String date) {
        List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
        replaceableAttributes.add(new ReplaceableAttribute(
                "historical_low_price", lowPrice, true));
        replaceableAttributes.add(new ReplaceableAttribute(
                "historical_low_price_date", date, true));
        sdb.putAttributes(new PutAttributesRequest(
                Domain.Monitored_Stock_Tickers.name(), ticker,
                replaceableAttributes));
    }

    public void cleanUpOpenOrdersTable() {
        String selectExpression = "select * from `"
                + Domain.Current_Open_Orders.name() + "` where accountId = '" + Constants.ACCOUNT_ID + "'";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        for (Item item : sdb.select(selectRequest).getItems()) {
            sdb.deleteAttributes(new DeleteAttributesRequest(
                    Domain.Current_Open_Orders.name(), item.getName()));
        }

    }

    public void updateOpenOrder(int orderId, String symbol, String secType,
            String orderType, int quantity, int permitId, double price,
            String action, double trailAmount) {
        List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
        replaceableAttributes.add(new ReplaceableAttribute("ticker", symbol,
                true));
        replaceableAttributes.add(new ReplaceableAttribute("action", action,
                true));
        replaceableAttributes.add(new ReplaceableAttribute("type", orderType,
                true));
        replaceableAttributes.add(new ReplaceableAttribute("sec_type", secType,
                true));
        replaceableAttributes.add(new ReplaceableAttribute("quantity", quantity
                + "", true));
        replaceableAttributes.add(new ReplaceableAttribute("price", price + "",
                true));
        replaceableAttributes.add(new ReplaceableAttribute("order_id", orderId
                + "", true));
        replaceableAttributes.add(new ReplaceableAttribute("accountId", Constants.ACCOUNT_ID, true));
        if (trailAmount > 0) {
            replaceableAttributes.add(new ReplaceableAttribute("trail_amount",
                    trailAmount + "", true));
        }

        sdb.putAttributes(new PutAttributesRequest(Domain.Current_Open_Orders
                .name(), permitId + "", replaceableAttributes));
    }

    public List<OptionPositionOrOrder> getOpenOptionOrders() {
        String selectExpression = "select * from `"
                + Domain.Current_Open_Orders.name() + "` where sec_type='OPT' and accountId='" + Constants.ACCOUNT_ID + "'";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        List<OptionPositionOrOrder> optionOrders = new ArrayList<OptionPositionOrOrder>();

        for (Item item : items) {
            OptionPositionOrOrder optionOrder = new OptionPositionOrOrder();
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("type")) {
                    optionOrder.setLimitOrder(attribute.getValue()
                            .equals("LMT"));
                } else if (attribute.getName().equals("action")) {
                    optionOrder.setAction(attribute.getValue());
                } else if (attribute.getName().equals("quantity")) {
                    optionOrder.setPosition(attribute.getValue());
                } else if (attribute.getName().equals("order_id")) {
                    optionOrder.setOrderId(attribute.getValue());
                } else if (attribute.getName().equals("ticker")) {
                    String tickerVal = attribute.getValue();
                    String[] tmp = tickerVal.split("   ");
                    optionOrder.setUnderlyingTick(tmp[0]);

                    String expiration = "20" + tmp[1].substring(0, 6);
                    optionOrder.setExpiration(expiration);

                    String putOrCall = tmp[1].substring(6, 7);
                    optionOrder.setCallOrPut(putOrCall);

                    String strikePrice = tmp[1].substring(10, 12);
                    optionOrder.setStrikePrice(strikePrice);
                }
            }
            optionOrders.add(optionOrder);
        }
        return optionOrders;
    }

    public List<StockPositionOrOrder> getOpenNonTrailStockOrder() {
        String selectExpression = "select * from `"
                + Domain.Current_Open_Orders.name()
                + "` where sec_type='STK' and type!='TRAIL LIMIT' and accountId='" + Constants.ACCOUNT_ID + "'";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        List<StockPositionOrOrder> stockOrders = new ArrayList<StockPositionOrOrder>();
        for (Item item : items) {
            StockPositionOrOrder stockOrder = new StockPositionOrOrder();
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("type")) {
                    stockOrder
                            .setLimitOrder(attribute.getValue().equals("LMT"));
                } else if (attribute.getName().equals("action")) {
                    stockOrder.setAction(attribute.getValue());
                } else if (attribute.getName().equals("quantity")) {
                    stockOrder.setQuantity(attribute.getValue());
                } else if (attribute.getName().equals("order_id")) {
                    stockOrder.setOrderId(attribute.getValue());
                } else if (attribute.getName().equals("ticker")) {
                    stockOrder.setTicker(attribute.getValue());
                }
            }
            stockOrders.add(stockOrder);
        }
        return stockOrders;
    }

    public List<StockPositionOrOrder> getOpenTrailOrder() {
        String selectExpression = "select * from `"
                + Domain.Current_Open_Orders.name()
                + "` where sec_type='STK' and type='TRAIL LIMIT' and accountId='" + Constants.ACCOUNT_ID + "'";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        List<StockPositionOrOrder> trailOrders = new ArrayList<StockPositionOrOrder>();
        for (Item item : items) {
            StockPositionOrOrder trailOrder = new StockPositionOrOrder();
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("ticker")) {
                    trailOrder.setTicker(attribute.getValue());
                } else if (attribute.getName().equals("quantity")) {
                    trailOrder.setQuantity(attribute.getValue());
                } else if (attribute.getName().equals("order_id")) {
                    trailOrder.setOrderId(attribute.getValue());
                } else if (attribute.getName().equals("action")) {
                    trailOrder.setAction(attribute.getValue());
                } else if (attribute.getName().equals("trail_amount")) {
                    trailOrder.setTrailAmount(attribute.getValue());
                }
            }
            trailOrders.add(trailOrder);
        }
        return trailOrders;
    }

    public void removeOpenOrder(int permitId) {
        sdb.deleteAttributes(new DeleteAttributesRequest(
                Domain.Current_Open_Orders.name(), permitId + ""));
    }

    public MonitoredStocks getMonitoredStockData(String ticker) {
        String selectExpression = "select * from `"
                + Domain.Monitored_Stock_Tickers.name()
                + "` where itemName() = '" + ticker + "'";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        Item item = sdb.select(selectRequest).getItems().get(0);

        MonitoredStocks monitoredStock = new MonitoredStocks();
        monitoredStock.setTicker(ticker);
        for (Attribute attribute : item.getAttributes()) {
            if (attribute.getName().equals("historical_low_price")) {
                monitoredStock.setHistoricalLow(Double.parseDouble(attribute
                        .getValue()));
            } else if (attribute.getName().equals("last_price")) {
                monitoredStock.setLastPrice(Double.parseDouble(attribute
                        .getValue()));
            } else if (attribute.getName().equals("historical_low_price_date")) {
                monitoredStock.setHistoricalLowDate(attribute.getValue());
            }
        }
        return monitoredStock;
    }

    public void updateMarketSentiment(String sentiment) {
        List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
        replaceableAttributes.add(new ReplaceableAttribute("sentiment",
                sentiment, true));
        sdb.putAttributes(new PutAttributesRequest(Domain.Market_Sentiment
                .name(), "0", replaceableAttributes));
    }

    public String getMarketSentiment() {
        String selectExpression = "select * from `"
                + Domain.Market_Sentiment.name() + "` where itemName() = '0'";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        Item item = sdb.select(selectRequest).getItems().get(0);

        for (Attribute attribute : item.getAttributes()) {
            if (attribute.getName().equals("sentiment")) {
                return attribute.getValue();
            }
        }

        return null;

    }

    /**
     * Giving today's VIX price, insert it into VIX table.
     * 
     * @param price
     */
    public void updateVIXSpotPriceTable(String price) {
        String selectExpression = "select * from `"
                + Domain.Past_Six_Day_VIX_Spot.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        Map<String, String> vixPrices = new HashMap<String, String>();
        for (Item item : items) {
            String itemPrice = "";
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("price")) {
                    itemPrice = attribute.getValue();
                }
            }
            vixPrices.put(item.getName(), itemPrice);
        }
        String toBeReplaced = price;
        for (int i = 0; i < 6; i++) {
            if (toBeReplaced == null) {
                break;
            }
            String tmp = vixPrices.get(i + "");
            vixPrices.put(i + "", toBeReplaced);
            toBeReplaced = tmp;
        }
        for (int i = 0; i < 6; i++) {
            String itemPrice = vixPrices.get(i + "");
            if (itemPrice == null) {
                break;
            }
            List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
            replaceableAttributes.add(new ReplaceableAttribute("price",
                    itemPrice, true));
            sdb.putAttributes(new PutAttributesRequest(
                    Domain.Past_Six_Day_VIX_Spot.name(), i + "",
                    replaceableAttributes));
        }

    }

    /**
     * Store VIX Future front month and second month VIXFuturePriceList : front
     * month index is 0, second month index is 1
     */
    public void updateVIXFuturePrice(List<Double> VIXFuturePriceList) {
        String selectExpression = "select * from `"
                + Domain.Past_Five_Day_VIX_Contango.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        Map<String, Map<String, String>> vixContango = new HashMap<String, Map<String, String>>();
        for (Item item : items) {
            Map<String, String> itemAttributes = new HashMap<String, String>();
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("contango")
                        || attribute.getName().equals("front_month")
                        || attribute.getName().equals("second_month")) {
                    itemAttributes.put(attribute.getName(),
                            attribute.getValue());
                }
            }
            vixContango.put(item.getName(), itemAttributes);
        }
        Double contango = (VIXFuturePriceList.get(1) - VIXFuturePriceList
                .get(0)) / VIXFuturePriceList.get(0);
        Map<String, String> toBeReplaced = new HashMap<String, String>();
        toBeReplaced.put("contango", contango + "");
        toBeReplaced.put("front_month", VIXFuturePriceList.get(0) + "");
        toBeReplaced.put("second_month", VIXFuturePriceList.get(1) + "");
        for (int i = 0; i < 5; i++) {
            if (toBeReplaced == null) {
                break;
            }
            Map<String, String> tmp = vixContango.get(i + "");
            vixContango.put(i + "", toBeReplaced);
            toBeReplaced = tmp;
        }

        for (int i = 0; i < 5; i++) {
            Map<String, String> itemContango = vixContango.get(i + "");
            if (itemContango == null) {
                break;
            }
            List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
            replaceableAttributes.add(new ReplaceableAttribute("contango",
                    itemContango.get("contango"), true));
            replaceableAttributes.add(new ReplaceableAttribute("front_month",
                    itemContango.get("front_month"), true));
            replaceableAttributes.add(new ReplaceableAttribute("second_month",
                    itemContango.get("second_month"), true));
            sdb.putAttributes(new PutAttributesRequest(
                    Domain.Past_Five_Day_VIX_Contango.name(), i + "",
                    replaceableAttributes));

        }
    }

    public List<String> getVIXFutureContango() {
        String selectExpression = "select contango from `"
                + Domain.Past_Five_Day_VIX_Contango.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        List<String> vixContango = new ArrayList<String>();
        for (Item item : items) {
            String itemVixContango = "";
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("contango")) {
                    itemVixContango = attribute.getValue();
                }
            }
            vixContango.add(itemVixContango);
        }

        return vixContango;
    }

    public List<String> getVIXFutureSecondMonth() {

        String selectExpression = "select second_month from `"
                + Domain.Past_Five_Day_VIX_Contango.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        List<String> vixSecondMonth = new ArrayList<String>();
        for (Item item : items) {
            String itemVixSecondMonth = "";
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("second_month")) {
                    itemVixSecondMonth = attribute.getValue();
                }
            }
            vixSecondMonth.add(itemVixSecondMonth);
        }

        return vixSecondMonth;
    }

    public Map<Integer, String> getVIXSpotPrices() {
        String selectExpression = "select price from `"
                + Domain.Past_Six_Day_VIX_Spot.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        List<Item> items = sdb.select(selectRequest).getItems();

        Map<Integer, String> vixSpotPrices = new HashMap<Integer, String>();
        for (Item item : items) {
            String itemVixSpot = "";
            for (Attribute attribute : item.getAttributes()) {
                if (attribute.getName().equals("price")) {
                    itemVixSpot = attribute.getValue();
                }
            }
            vixSpotPrices.put(Integer.parseInt(item.getName()), itemVixSpot);
        }
        return vixSpotPrices;
    }

    public void cleanUpCurrentStockPositions() {
        String selectExpression = "select * from `"
                + Domain.Current_Stock_Positions.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        for (Item item : sdb.select(selectRequest).getItems()) {
            String itemName = item.getName();
            if (itemName.split("_")[1].equals(Constants.ACCOUNT_ID)) {
                sdb.deleteAttributes(new DeleteAttributesRequest(
                        Domain.Current_Stock_Positions.name(), item.getName()));
            }
        }
    }
    
    public void cleanUpAccountStatus() {
        String selectExpression = "select * from `"
                + Domain.Current_Account_Status.name() + "` where itemName() = '" + Constants.ACCOUNT_ID + "'";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        for (Item item : sdb.select(selectRequest).getItems()) {
            sdb.deleteAttributes(new DeleteAttributesRequest(
                    Domain.Current_Account_Status.name(), item.getName()));
        }
    }

    public void cleanUpCurrentOptionPositions() {
        String selectExpression = "select * from `"
                + Domain.Current_Option_Positions.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        for (Item item : sdb.select(selectRequest).getItems()) {
            String[] components = item.getName().split(" ");
            if (!components[4].equals(Constants.ACCOUNT_ID)) {
                continue;
            }
            sdb.deleteAttributes(new DeleteAttributesRequest(
                    Domain.Current_Option_Positions.name(), item.getName()));
        }
    }

    public void cleanUpVIXSpot() {
        String selectExpression = "select * from `"
                + Domain.Past_Six_Day_VIX_Spot.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        for (Item item : sdb.select(selectRequest).getItems()) {
            sdb.deleteAttributes(new DeleteAttributesRequest(
                    Domain.Past_Six_Day_VIX_Spot.name(), item.getName()));
        }
    }

    public void cleanUpVIXContango() {
        String selectExpression = "select * from `"
                + Domain.Past_Five_Day_VIX_Contango.name() + "`";
        SelectRequest selectRequest = new SelectRequest(selectExpression);
        for (Item item : sdb.select(selectRequest).getItems()) {
            sdb.deleteAttributes(new DeleteAttributesRequest(
                    Domain.Past_Five_Day_VIX_Contango.name(), item.getName()));
        }
    }
    
    public int getHighestOrderId() {
        List<OptionPositionOrOrder> optionOrders = this.getOpenOptionOrders();
        List<StockPositionOrOrder> stockOrders = this.getOpenNonTrailStockOrder();
        stockOrders.addAll(this.getOpenTrailOrder());
        
        int highestOrderId = 0;
        for (OptionPositionOrOrder optionOrder : optionOrders) {
            int orderId = Integer.parseInt(optionOrder.getOrderId());
            if (orderId > highestOrderId) {
                highestOrderId = orderId;
            }
        }
        for (StockPositionOrOrder stockOrder : stockOrders) {
            int orderId = Integer.parseInt(stockOrder.getOrderId());
            if (orderId > highestOrderId) {
                highestOrderId = orderId;
            }
        }
        return highestOrderId;
    }
}
